home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / GLX / littleRedCap / gl_interfere.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  13.0 KB  |  602 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <sys/types.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <math.h>
  21. #include <X11/Intrinsic.h>
  22. #include <X11/Xirisw/GlxMDraw.h>
  23. #include <Xm/Xm.h>
  24. #include <gl/gl.h>
  25.  
  26. #include "shapes.h"
  27. #include "interfere.h"
  28.  
  29. #define STEN_SIZE 4
  30. #define STEN_MASK ((1 << STEN_SIZE) - 1)
  31.  
  32. /*
  33.  * Material indeces.
  34.  */
  35. #define BLUE_PLASTIC_INDEX 1
  36. #define GREEN_PLASTIC_INDEX 2
  37. #define BRASS_INDEX 3
  38.  
  39. /*
  40.  * Sundry graphics stuff ... dimensions etc.
  41.  */
  42. #define VIEWPOINT_Z 8.
  43. #define PLANE_LENGTH 2.
  44. #define MAX_CLIP_PLANE 6
  45. #define ANGLE_DELTA 10
  46.  
  47. #define NUMBER(array) ((unsigned long) (sizeof(array) / sizeof(array[0])))
  48.  
  49. typedef struct tagTransformation
  50. {
  51.     float depth;
  52.     float scale;
  53.     unsigned int x_rot, y_rot, z_rot;
  54. } Transformation, * TransformationPtr;
  55.  
  56. /*
  57.  * The viewing, clipping, and modeling transformations are stored
  58.  * in the same array.
  59.  */
  60. enum
  61. {
  62.     VIEWING_TRANSFORMATION = 0,
  63.     CLIPPING_TRANSFORMATION,
  64.     MODEL_TRANSFORMATION = CLIPPING_TRANSFORMATION + MAX_CLIP_PLANE
  65. };
  66.  
  67. typedef void (*Method) (void);
  68.  
  69. typedef struct tagShape
  70. {
  71.     Method constructor;
  72.     GL_Object object;
  73.     unsigned long material;
  74.     Transformation transform;
  75. } Shape, * ShapePtr;
  76.  
  77. /*
  78.  * Here are the generalized transforms.  The array looks like this :
  79.  *  0   : Viewing transformation.
  80.  *  1-n : Clipping plane transformations.
  81.  *  n   : Modeling transformation.  These are applied to all
  82.  *        of the shapes.  Transforms applied to one shape only
  83.  *        are stored with the shape info.
  84.  */
  85. static Transformation 
  86. transformations[] = {{VIEWPOINT_Z, 1., 20, 340, 0},
  87.                      {0., 1., 0, 180, 0},
  88.                      {0., 1., 0, 0, 0},
  89.                      {0., 1., 0, 0, 0},
  90.                      {0., 1., 0, 0, 0},
  91.                      {0., 1., 0, 0, 0},
  92.                      {0., 1., 0, 0, 0},
  93.                      {0., 1., 0, 0, 0}
  94.                     };
  95.  
  96. /*
  97.  * Shape info.
  98.  */
  99. static Shape shapes[] = {{ftorus, 0, BLUE_PLASTIC_INDEX, {0., 1., 0, 0, 0}},
  100.                          {ftorus, 0, GREEN_PLASTIC_INDEX, {0., 1., 90, 0, 0}},
  101.                         };
  102.  
  103. static Matrix 
  104. identity = {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};
  105.  
  106. static GL_Object white_axes = 0;
  107.  
  108. /*
  109.  * Set up a short far clipping plane.
  110.  */
  111. static void
  112. setShortViewingVolume (void)
  113. {
  114.     perspective(600, 1., 0.25, 15.);
  115. }
  116.  
  117. /*
  118.  * Set up a long far clipping plane.
  119.  */
  120. static void
  121. setLongViewingVolume (void)
  122. {
  123.     perspective(600, 1., 0.25, 10000.);
  124. }
  125.  
  126. /*
  127.  *
  128.  */
  129. static void
  130. setupProjection (void)
  131. {
  132.     loadmatrix(identity);
  133.     setLongViewingVolume ();
  134. }
  135.  
  136. /*
  137.  * Define and bind the lighting model and lights.  Define
  138.  * the material indices.
  139.  */
  140. static void 
  141. defineLighting (void)
  142. {
  143.     float light_model[] =
  144.     {
  145.         AMBIENT, 0.1, 0.1, 0.1,
  146.         LOCALVIEWER, 0.0,
  147.         TWOSIDE, 1.0,
  148.         LMNULL,
  149.     };
  150.  
  151.     float white_light1[] =
  152.     {
  153.         LCOLOR, 1.0, 1.0, 1.0,
  154.         POSITION, -1., 1, VIEWPOINT_Z, 0.0,
  155.         LMNULL,
  156.     };
  157.  
  158.     float white_light2[] =
  159.     {
  160.         LCOLOR, 1.0, 1.0, 1.0,
  161.         POSITION, 1., 1., VIEWPOINT_Z, 0.0,
  162.         LMNULL,
  163.     };
  164.     float blue_plastic[] =
  165.     {
  166.         AMBIENT, 0.1, 0.1, 0.5,
  167.         DIFFUSE, 0.1, 0.1, 0.5,
  168.         SPECULAR, 0.45, 0.45, 0.45,
  169.         SHININESS, 30.0,
  170.         LMNULL,
  171.     };
  172.  
  173.     float green_plastic[] =
  174.     {
  175.         AMBIENT, 0.1, 0.5, 0.1,
  176.         DIFFUSE, 0.1, 0.5, 0.1,
  177.         SPECULAR, 0.45, 0.45, 0.45,
  178.         SHININESS, 30.0,
  179.         LMNULL,
  180.     };
  181.  
  182.     float brass[] =
  183.     {
  184.         AMBIENT, 0.65, 0.5, 0.35,
  185.         DIFFUSE, 0.65, 0.5, 0.35,
  186.         SPECULAR, 0.0, 0.0, 0.0,
  187.         SHININESS, 5.0,
  188.         LMNULL,
  189.     };
  190.  
  191.     lmdef(DEFMATERIAL, BLUE_PLASTIC_INDEX, 0, blue_plastic);
  192.     lmdef(DEFMATERIAL, GREEN_PLASTIC_INDEX, 0, green_plastic);
  193.     lmdef(DEFMATERIAL, BRASS_INDEX, 0, brass);
  194.     lmdef(DEFLMODEL, 1, 0, light_model);
  195.     lmdef(DEFLIGHT, 1, 0, white_light1);
  196.     lmdef(DEFLIGHT, 2, 0, white_light2);
  197.  
  198.     lmbind(LMODEL, 1);
  199.     lmbind(LIGHT0, 1);
  200.     lmbind(LIGHT1, 2);
  201. }
  202.  
  203. /*
  204.  * Create a display list for the axes.
  205.  */
  206. static void
  207. whiteAxes(void)
  208. {
  209.     makeobj(white_axes = genobj());
  210.      cpack(0xffffffff);
  211.      pushmatrix();
  212.       scale(2., 2., 2.);
  213.       axes();
  214.      popmatrix();
  215.     closeobj();
  216. }
  217.  
  218. /*
  219.  * Initialize the shapes array.
  220.  */
  221. static void
  222. initShapes (void)
  223. {
  224.     unsigned long i = 0;
  225.  
  226.     for (i = 0; i < NUMBER(shapes); i++) {
  227.         makeobj(shapes[i].object = genobj());
  228.          lmbind(MATERIAL, shapes[i].material);
  229.          (*(shapes[i].constructor))();
  230.          lmbind(MATERIAL, 0);
  231.         closeobj();
  232.     }
  233. }
  234.  
  235. /*
  236.  * Entry point to initialize graphics.
  237.  */
  238. void
  239. initGraphics (void)
  240. {
  241.     mmode(MVIEWING);
  242.     zbuffer(TRUE);
  243.     if (!getgdesc(GD_BITS_STENCIL)) {
  244.         fprintf(stderr, "Stenciling is not available\n");
  245.         exit(1);
  246.     }
  247.     sclear(0);
  248.     lsetdepth(getgdesc(GD_ZMIN), getgdesc(GD_ZMAX));
  249.     setupProjection();
  250.     defineLighting ();
  251.     whiteAxes();
  252.     initShapes();
  253. }
  254.  
  255. /*
  256.  * Called by the GLwDrawingArea widget before it is managed.
  257.  */
  258. static void
  259. initCallback (Widget w, XtPointer client, XtPointer callback)
  260. {
  261.     GlxDrawCallbackStruct * call_data = (GlxDrawCallbackStruct *)callback;
  262.     GLXwinset(XtDisplay(w), call_data->window);
  263.     initGraphics();
  264. }
  265.  
  266. /*
  267.  * Isolated for reshapeviewport()
  268.  */
  269. static void
  270. resizeCallback (Widget w, XtPointer client, XtPointer callback)
  271. {
  272.     reshapeviewport();
  273.     setupProjection();
  274. }
  275.  
  276. /*
  277.  * Specify the rendering area, and draw the scene.
  278.  */
  279. static void
  280. exposeCallback (Widget w, XtPointer client, XtPointer callback)
  281. {
  282.     GlxDrawCallbackStruct * call_data = (GlxDrawCallbackStruct *)callback;
  283.     GLXwinset(XtDisplay(w), call_data->window);
  284.     drawScene();
  285. }
  286.  
  287. /*
  288.  * Create the GL drawing area widget.
  289.  */
  290. Widget
  291. initGLWidget (Widget parent, unsigned int width, unsigned int height)
  292. {
  293.     GLXconfig rgb_mode[] =
  294.     {
  295.         {GLX_NORMAL, GLX_RGB, TRUE},
  296.         {GLX_NORMAL, GLX_DOUBLE, TRUE},
  297.         {GLX_NORMAL, GLX_ZSIZE, GLX_NOCONFIG},
  298.         {GLX_NORMAL, GLX_STENSIZE, STEN_SIZE},
  299.         {0, 0, 0},
  300.     };
  301.     Arg args[0x20];
  302.     int n = 0;
  303.     Widget canvas;
  304.  
  305.     XtSetArg(args[n], GlxNglxConfig, rgb_mode); n++;
  306.     XtSetArg(args[n], XmNwidth, width); n++;
  307.     XtSetArg(args[n], XmNheight, height); n++;
  308.  
  309.     canvas = (Widget)GlxCreateMDraw(parent, "canvas", args, n);
  310.  
  311.     XtAddCallback(canvas, GlxNginitCallback, initCallback, NULL);
  312.     XtAddCallback(canvas, GlxNexposeCallback, exposeCallback, NULL);
  313.     XtAddCallback(canvas, GlxNresizeCallback, resizeCallback, NULL);
  314.  
  315.     XtManageChild(canvas);
  316.  
  317.     return canvas;
  318. }
  319.  
  320. /*
  321.  * Increment the modeling transformation angles (called once for
  322.  * each drawScene()).
  323.  */
  324. static void 
  325. updateAngles (void)
  326. {
  327.     transformations[MODEL_TRANSFORMATION].x_rot = 
  328.      (transformations[MODEL_TRANSFORMATION].x_rot + ANGLE_DELTA) % 3600;
  329.     transformations[MODEL_TRANSFORMATION].z_rot = 
  330.      (transformations[MODEL_TRANSFORMATION].z_rot + ANGLE_DELTA) % 3600;
  331. }
  332.  
  333. /*
  334.  * Do the viewing transformation.
  335.  */
  336. static void
  337. doViewingTransformation (void)
  338. {
  339.     translate(0., 0.,-transformations[VIEWING_TRANSFORMATION].depth);
  340.     rot(transformations[VIEWING_TRANSFORMATION].x_rot, 'x');
  341.     rot(transformations[VIEWING_TRANSFORMATION].y_rot, 'y');
  342.     rot(transformations[VIEWING_TRANSFORMATION].z_rot, 'z');
  343. }
  344.  
  345. /*
  346.  * Do a modeling (or clipping) and viewing transformation.
  347.  */
  348. static void
  349. doTransformation (unsigned int index)
  350. {
  351.     doViewingTransformation();
  352.         /* Modeling. */
  353.     scale(transformations[index].scale, transformations[index].scale, 
  354.           transformations[index].scale);
  355.     translate(0., 0., transformations[index].depth);
  356.     rot(transformations[index].x_rot, 'x');
  357.     rot(transformations[index].y_rot, 'y');
  358.     rot(transformations[index].z_rot, 'z');
  359. }
  360.  
  361. /*
  362.  * Do a clipping and viewing transformation.
  363.  */
  364. static void
  365. doClippingTransformation (unsigned int clip_plane)
  366. {
  367.     doTransformation(CLIPPING_TRANSFORMATION + clip_plane);
  368. }
  369.  
  370. /*
  371.  * Do a modeling transformation.
  372.  */
  373. static void
  374. doModelingTransformation (void)
  375. {
  376.     doTransformation(MODEL_TRANSFORMATION);
  377. }
  378.  
  379. /*
  380.  * Draw the clipping plane.  Presumes that the clipping plane is 
  381.  * properly oriented.
  382.  */
  383. static void
  384. drawClipPlanes (void)
  385. {
  386.     float clipplane_vertices[4][3] = {
  387.         {PLANE_LENGTH, -PLANE_LENGTH, 0.},
  388.         {-PLANE_LENGTH, -PLANE_LENGTH, 0.},
  389.         {-PLANE_LENGTH, PLANE_LENGTH, 0.},
  390.         {PLANE_LENGTH, PLANE_LENGTH, 0.},
  391.     };
  392.  
  393.     cpack(0xff00ffff);
  394.     bgnclosedline();
  395.      v3f(clipplane_vertices[0]);
  396.      v3f(clipplane_vertices[1]);
  397.      v3f(clipplane_vertices[2]);
  398.      v3f(clipplane_vertices[3]);
  399.     endclosedline();
  400.     cpack(0x0000000000);
  401. }
  402.  
  403. /*
  404.  * Draw a capping rectangle over clipped portions of
  405.  * a shape.
  406.  * 
  407.  */
  408. static void
  409. drawCap (unsigned long cap_color)
  410. {
  411.     float cap_vertices[4][4] = {
  412.         {-1, -1, 0., 1.},
  413.         { 1, -1, 0., 1.},
  414.         {-1,  1, 0., 1.},
  415.         { 1,  1, 0., 1.},
  416.     };
  417.  
  418.         /*
  419.           Always update the z values.  Turn on stenciling and increment
  420.           for each pixel that has a count equal to one.  This means
  421.           that we will only draw where we did not draw before.  Doing 
  422.           the clipping transform after this is crucial.
  423.          */
  424.     zfunction(ZF_ALWAYS);
  425.     stencil(TRUE, 1, SF_EQUAL, 0x1, ST_KEEP, ST_KEEP, ST_INCR);
  426.     clipplane(0, CP_OFF, 0);
  427.  
  428.     pushmatrix();
  429.         /* 
  430.           Go to the location of the clipping plane.
  431.          */
  432.      doClippingTransformation(0);
  433.  
  434.         /*
  435.           * Cap in the same material as the shape.
  436.          */
  437.      lmbind(MATERIAL, cap_color);
  438.      pushmatrix();
  439.  
  440.         /*
  441.          * Make the polygon enormous enough to cover the exposed portion
  442.          * of the clipped polygon.
  443.          */
  444.       scale(100., 100., 100.);
  445.       bgnpolygon();
  446.        v3f(cap_vertices[0]);
  447.        v3f(cap_vertices[2]);
  448.        v3f(cap_vertices[3]);
  449.        v3f(cap_vertices[1]);
  450.       endpolygon();
  451.      popmatrix();
  452.      lmbind(MATERIAL, 0);
  453.     popmatrix();
  454.  
  455.         /*
  456.          * Restore the zbuffer and stencil buffer states.
  457.          */
  458.     zfunction(ZF_LEQUAL);
  459.     stencil(FALSE, 0, 0, 0, 0, 0, 0);
  460. }
  461.  
  462. /*
  463.  * Render a shape (clipped, not yet capped).  The shape's
  464.  * transformations must be applied relative to the overall
  465.  * modeling transformation.  It appears that storing a 
  466.  * transformation in a display list simply does a loadmatrix()
  467.  * and no multiply relative to the MVM when the display list
  468.  * is called.
  469.  */
  470. static void
  471. drawObject (unsigned long index)
  472. {
  473.     pushmatrix();
  474.      scale(shapes[index].transform.scale, shapes[index].transform.scale,
  475.            shapes[index].transform.scale);
  476.      translate(0., 0., shapes[index].transform.depth);
  477.      rot(shapes[index].transform.x_rot, 'x');
  478.      rot(shapes[index].transform.y_rot, 'y');
  479.      rot(shapes[index].transform.z_rot, 'z');
  480.      callobj(shapes[index].object);
  481.     popmatrix();
  482. }
  483.  
  484. /*
  485.  * Draw a capped shape.
  486.  */
  487. static void
  488. drawCappedObject (unsigned long index)
  489. {
  490.     pushmatrix();
  491.  
  492.         /*
  493.          * This is the overall modeling transformation.
  494.          */
  495.      doModelingTransformation();
  496.  
  497.         /*
  498.          * Turn the clipping plane on and enable backface culling
  499.          * (since we don't need to draw what we won't see due to the
  500.          * capping anyway).  Then draw the uncapped object.
  501.          */
  502.      clipplane(0, CP_ON, 0);
  503.      backface(TRUE);
  504.      drawObject(index);
  505.      backface(FALSE);
  506.  
  507.         /*
  508.          * Set up a short far clipping plane in the viewing volume.
  509.          * Render the shape again, this time writing only to the 
  510.          * stencil buffer.  This time we're gathering the information
  511.          * that will tell us which parts of the shape need to be capped
  512.          * (referenced by pixel).
  513.          */
  514.      setShortViewingVolume();
  515.      zbuffer(FALSE);
  516.      wmpack(0x00000000);
  517.      swritemask(0x1);
  518.  
  519.         /*
  520.          * Check the LSB of the stencil value for a hit by the rendered
  521.          * object.  Count even-odd.
  522.          */
  523.      stencil(TRUE, 0, SF_ALWAYS, 0x01, ST_INVERT, ST_INVERT, ST_INVERT);
  524.      drawObject(index);
  525.      setLongViewingVolume();
  526.      zbuffer(TRUE);
  527.      wmpack(0xffffffff);
  528.      swritemask(0xff);
  529.     popmatrix();
  530.  
  531.         /* 
  532.          * Draw the capped regions.
  533.          */
  534.     drawCap (shapes[index].material);
  535. }
  536.  
  537. /*
  538.  * Render the intersections in red.
  539.  */
  540. static void
  541. drawInterferenceRegion (void)
  542. {
  543.     stencil(TRUE, 2, SF_LESS, STEN_MASK, ST_ZERO, ST_ZERO, ST_ZERO);
  544.     zfunction(ZF_ALWAYS);
  545.  
  546.         /*
  547.          * Set the projection matrix to a 2d orthographic projection
  548.          * and render a polygon over the entire porjection area.  It will
  549.          * only show up in the areas in which the stencil values are
  550.          * two or more.
  551.          */
  552.     ortho2(0, 1, 0, 1);
  553.     pushmatrix();
  554.      loadmatrix(identity);
  555.      cpack(0x0000ff);
  556.      rectfi(0, 0, 1, 1);
  557.     popmatrix();
  558.     setLongViewingVolume ();
  559.  
  560.     zfunction(ZF_LEQUAL);
  561.     stencil(FALSE, 0, 0, 0, 0, 0, 0);
  562. }
  563.  
  564. /*
  565.  * Draw the interfering objects, swap the buffers, and update the
  566.  * angles for rotation.
  567.  */
  568. void 
  569. drawScene (void)
  570. {
  571.     unsigned long i = 0;
  572.     float cp[4] = {0, 0, 1, 0};
  573.  
  574.     swritemask(0xff);
  575.     czclear(0x0, getgdesc(GD_ZMAX));
  576.  
  577.         /* Define the clipping plane after setting up the 
  578.            proper model view matrix. */
  579.     pushmatrix();
  580.      doClippingTransformation(0);
  581.      clipplane(0, CP_DEFINE, cp);
  582.     popmatrix();
  583.  
  584.     pushmatrix();
  585.      doViewingTransformation();
  586.      callobj(white_axes);
  587.      drawClipPlanes ();
  588.     popmatrix();
  589.  
  590.     pushmatrix();
  591.      for (i = 0; i < NUMBER(shapes); i++) {
  592.          drawCappedObject(i);
  593.      }
  594.      drawInterferenceRegion();
  595.     popmatrix();
  596.  
  597.     swapbuffers();
  598.  
  599.     updateAngles();
  600. }
  601.  
  602.